# 使用OpenCV库进行Harris角点检测并标记显示

import cv2
import numpy as np


def detect_corner_harris(image_path):
    # 读取图像
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 图像梯度
    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
    # Harris角点检测
    dst = cv2.cornerHarris(gray, 2, 5, 0.15)
    # 标记角点
    image[dst > 0.01 * dst.max()] = [0, 0, 255]  # 在图像上标记角点为红色
    threshold = 0.01 * dst.max()
    corners = []
    # 设置红色（BGR）
    red_color = (0, 0, 255)
    # 设置文本的颜色（白色）
    text_color = (255, 0, 255)
    # 设置文本字体和大小
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 0.5
    # 设置文本厚度
    thickness = 1
    # 设置圆圈的半径
    circle_radius = 2

    i = 0
    for y in range(dst.shape[0]):
        for x in range(dst.shape[1]):
            # 如果当前像素的响应强度大于阈值，则记录其坐标
            if dst[y, x] > threshold:
                corners.append((x, y))  # 显示图像
    for corner in corners:
        x, y = corner
        grad_x = sobelx[y, x]
        grad_y = sobely[y, x]
        # 计算梯度幅度和方向
        magnitude = np.sqrt(grad_x ** 2 + grad_y ** 2)
        angle = np.arctan2(grad_y, grad_x) * (180 / np.pi)  # 转换为角度
        cv2.circle(image, (x, y), circle_radius, red_color, thickness=-1)
        text_x = x + circle_radius + 2
        text_y = y
        # 将角点的序号转换为字符串
        label = str(i + 1)
        cv2.putText(image, label, (text_x, text_y), font, font_scale, text_color, thickness, cv2.LINE_AA)

        i = i + 1
        print(f"角点 {i} 坐标: ({x}, {y}) 梯度幅度： {magnitude}  梯度方向  {angle}")
    cv2.imshow('Harris Corners', image)


def detect_corner_tomasi(image_path):
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
    features = cv2.goodFeaturesToTrack(gray, maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
    cv2.imshow('Shi-Tomasi Corner sobelx', sobelx)
    cv2.imshow('Shi-Tomasi Corner sobely', sobely)

    red_color = (0, 0, 255)
    # 设置文本的颜色（白色）
    text_color = (0, 0, 0)
    # 设置文本字体和大小
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 0.5
    # 设置文本厚度
    thickness = 1
    # 设置圆圈的半径
    circle_radius = 2
    i = 0

    # 在图像上绘制角点
    for x, y in features.reshape((-1, 2)):
        x = int(x)
        y = int(y)
        grad_x = sobelx[y, x]
        grad_y = sobely[y, x]
        # 计算梯度幅度和方向
        magnitude = np.sqrt(grad_x ** 2 + grad_y ** 2)
        angle = np.arctan2(grad_y, grad_x) * (180 / np.pi)  # 转换为角度
        cv2.circle(image, (x, y), circle_radius, red_color, thickness=-1)
        text_x = x + circle_radius + 2
        text_y = y
        # 将角点的序号转换为字符串
        label = str(i + 1)
        cv2.putText(image, label, (text_x, text_y), font, font_scale, text_color, thickness, cv2.LINE_AA)

        i = i + 1
        print(f"角点 {i} 坐标: ({x}, {y}) 梯度幅度： {magnitude}  梯度方向  {angle}")
    # 显示结果
    cv2.imshow('Shi-Tomasi Corner Detection', image)


def main():
    file_name = 'imgs/birdview.png'
    # detect_corner_harris(file_name)
    detect_corner_tomasi(file_name)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()
